package com.ettractions.kiosk.mediators
{
	import com.ettractions.kiosk.components.ThumbnailRibbon;
	import com.ettractions.kiosk.events.BrochureSelectEvent;
	import com.ettractions.kiosk.models.KioskModel;
	import com.ettractions.kiosk.vo.BrochureVO;
	import com.greensock.TweenLite;
	import com.greensock.easing.Bounce;
	import com.greensock.easing.Elastic;
	
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.collections.ArrayList;
	import mx.events.ItemClickEvent;
	
	import nl.demonsters.debugger.MonsterDebugger;
	
	import org.robotlegs.mvcs.Mediator;
	
	import spark.components.supportClasses.ItemRenderer;
	
	public class ThumbnailRibbonMediator extends Mediator
	{
		private static const LIST_ITEM_COUNT:uint = 23;
		
		private static const DISPLAYED_LIST_ITEM_COUNT:uint = 7;
		
		private static const LIST_IDLE_X:int = -1311;
		
		private static const TWEEN_DURATION:Number = 0.5;
		
		[Inject]
		public var model:KioskModel;
		
		[Inject]
		public var view:ThumbnailRibbon;
		
		private var _tween:TweenLite;
		
		private var _dragStartPoint:Point;
		
		private var _mouseDownOnCenterItem:Boolean;
		
		private var _previousBrochureIndex:int = -1;
		
		private var _dragging:Boolean = false;
		
		private var _preDragMiddleItemIndex:int;
		
		private var _currentMiddleItemIndex:int;		
		
		override public function onRegister():void
		{
			view.visible = false;
			
			view.list.mask = view.listMask;
			
			eventDispatcher.addEventListener(BrochureSelectEvent.BROCHURE_SELECTED, handleBrochureSelected);
			
			view.dragArea.addEventListener(MouseEvent.MOUSE_DOWN, handleDragAreaMouseDown);
			
			view.previousButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
			view.nextButton.addEventListener(MouseEvent.CLICK, handleButtonClick);			
		}
		
		private function populateList(centerIndex:int):void
		{
			var listDataProvider:ArrayList = new ArrayList();
			var listStartIndex:int = centerIndex - Math.floor(LIST_ITEM_COUNT / 2);
			
			if (listStartIndex < 0)
				listStartIndex = model.brochures.length + listStartIndex;
			
			for (var i:uint=listStartIndex; i<model.brochures.length; i++)
			{
				listDataProvider.addItem(model.brochures[i]);
				
				if (listDataProvider.length == LIST_ITEM_COUNT)
					break;
			}
			
			if (listDataProvider.length < LIST_ITEM_COUNT)
			{
				var addItemCount:uint = LIST_ITEM_COUNT - listDataProvider.length;
				
				for (i=0; i<addItemCount; i++)
					listDataProvider.addItem(model.brochures[i]);
			}
			
			view.list.dataProvider = listDataProvider;
			view.list.selectedIndex = Math.floor(LIST_ITEM_COUNT / 2);
			view.list.x = LIST_IDLE_X;			
		}		
		
		private function tweenToItem(index:int):void
		{
			_tween = new TweenLite(
				view.list,
				TWEEN_DURATION,
				{
					x:LIST_IDLE_X + view.list.dataGroup.getElementAt(0).width * (Math.floor(LIST_ITEM_COUNT / 2) - index),
					onComplete:handleTweenComplete,
					onCompleteParams:[index]
				}
			);
		}
		
		private function getItemUnderGlobalPointIndex(point:Point):int
		{
			for (var i:uint=0; i<LIST_ITEM_COUNT; i++)
				if (ItemRenderer(view.list.dataGroup.getElementAt(i)).hitTestPoint(point.x, point.y))
					return i;
			
			return -1;
		}
				
		private function handleBrochureSelected(event:BrochureSelectEvent):void
		{
			if (event.brochure == null)
				view.visible = false;
			
			else if (!view.visible)
			{
				populateList(event.index);
				
				view.visible = true;
			}
			
			else if (!_dragging
			&& event.index != _previousBrochureIndex)
			{
				if (Math.abs(event.index - _previousBrochureIndex) <= DISPLAYED_LIST_ITEM_COUNT)
					tweenToItem(Math.floor(LIST_ITEM_COUNT / 2) + event.index - _previousBrochureIndex);
				
				else
					populateList(event.index);
			}
			
			_previousBrochureIndex = event.index;
		}
		
		private function handleDragAreaMouseDown(event:MouseEvent):void
		{
			if (!_tween)
			{
				_dragStartPoint = view.dragArea.localToGlobal(new Point(view.dragArea.mouseX, view.dragArea.mouseY));
				
				_mouseDownOnCenterItem = ItemRenderer(view.list.dataGroup.getElementAt(Math.floor(LIST_ITEM_COUNT / 2))).hitTestPoint(_dragStartPoint.x, _dragStartPoint.y);
				
				view.list.startDrag(false, new Rectangle(-3000, 0, 3000, 0));
				
				view.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
				
				view.stage.addEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
				
				_currentMiddleItemIndex = getItemUnderGlobalPointIndex(view.dragArea.localToGlobal(new Point(view.dragArea.width / 2, view.dragArea.y)));
				
				_dragging = true;				
			}
		}
		
		private function handleMouseMove(event:MouseEvent):void
		{
			var middleItemIndex:int = getItemUnderGlobalPointIndex(view.dragArea.localToGlobal(new Point(view.dragArea.width / 2, view.dragArea.y)));
			
			if (_currentMiddleItemIndex != middleItemIndex)
			{
				model.offsetBrochureIndex(middleItemIndex - _currentMiddleItemIndex);			
				
				_currentMiddleItemIndex = middleItemIndex;
			}
		}		
		
		private function handleStageMouseUp(event:MouseEvent):void
		{
			var middleItemIndex:int = Math.floor(LIST_ITEM_COUNT / 2);
			
			view.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
			
			view.stage.removeEventListener(MouseEvent.MOUSE_UP, handleStageMouseUp);
			
			view.list.stopDrag();
			
			_dragging = false;
			
			// Click
			if (_dragStartPoint.equals(view.dragArea.localToGlobal(new Point(view.dragArea.mouseX, view.dragArea.mouseY))))
			{
				if (!_mouseDownOnCenterItem)
					model.offsetBrochureIndex(getItemUnderGlobalPointIndex(_dragStartPoint) - middleItemIndex);
			}
			
			// Drag
			else
				tweenToItem(_currentMiddleItemIndex);
		}
		
		private function handleTweenComplete(index:int):void
		{
			_tween = null;
			
			populateList(model.selectedBrochureIndex);
		}
		
		private function handleButtonClick(event:MouseEvent):void
		{
			switch (event.target)
			{
				case view.previousButton:
					model.offsetBrochureIndex(-1);
					break;
				
				case view.nextButton:
					model.offsetBrochureIndex(1);
					break;				
			}
		}
	}
}